package com.ry.jwtexp.jwt;

import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

import java.util.Date;
import java.util.Objects;

/**
 * @Author ry
 * @Description
 * @Date 2020/8/31 17:44
 */
public class TokenUtils {
    /**
     * 创建秘钥
     */
    private static final byte[] SECRET = "6MNSobBRCHGIO0fS6MNSobBRCHGIO0fS".getBytes();

    /**
     * 过期时间  默认10分钟
     */
    private static final long EXPIRE_TIME = 1000*60*10;


    /**
     * 生成token
     * @param account
     * @return
     */
    public static String buildJWT(String account){

        try{
            /**
             * 1.创建一个生成32byte的密钥
             */
            MACSigner macSigner = new MACSigner(SECRET);

            /**
             * 2.建立payload载体
             * JWT Claims
             * “iss” (issuer)  发行人
             * “sub” (subject)  主题
             * “aud” (audience) 接收方 用户
             * “exp” (expiration time) 到期时间
             * “nbf” (not before)  在此之前不可用
             * “iat” (issued at)  jwt的签发时间
             * “jti” (JWT ID)  jwt的唯一身份标识，主要用来作为一次性token,从而回避重放攻击。
             */
            JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                    .subject("TokenCertificationCenter")
                    .issuer("ry.top")
                    .expirationTime(new Date(System.currentTimeMillis() + EXPIRE_TIME))
                    .claim("ACCOUNT",account).build();

            /**
             * 3.建立签名
             */
            SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256),claimsSet);
            signedJWT.sign(macSigner);

            /**
             * 4.生成token
             */
            String token = signedJWT.serialize();
            return token;

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;

    }

    /**
     * 校验token
     * @param token
     * @return
     */
    public static String validToken(String token){
        try{
            SignedJWT jwt = SignedJWT.parse(token);
            JWSVerifier verifier = new MACVerifier(SECRET);
            //校验是否有效
            if(!jwt.verify(verifier)){
                //Token无效
            }

            //校验是否超时
            Date expirationTime = jwt.getJWTClaimsSet().getExpirationTime();
            if(new Date().after(expirationTime)){
                // Token已过期
            }

            //获取载体中的数据
            Object account = jwt.getJWTClaimsSet().getClaim("ACCOUNT");
            //是否拥有openUid
            if(Objects.isNull(account)){
                //账号为空
            }

            return account.toString();

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
